/**
  ******************************************************************************
  * @file           : sddriver.h
  * @brief          : Header for sddriver.c file.
  *                   This file contains the common defines of the application.
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __SDDRIVER_H
#define __SDDRIVER_H

#include <stdint.h>
#include <bsp.h>
#include "sdiobsp.h"

#define SD_DRIVER_USE_DMA

#ifndef SD_DRIVER_USE_DMA
#define SD_DRIVER_USE_IT
#endif

#define SD_DRVMSG_DMATX_TEERR      0x01u
#define SD_DRVMSG_DMATX_FEERR      0x02u
#define SD_DRVMSG_DMATX_DMEERR     0x04u
#define SD_DRVMSG_DMARX_TEERR      0x08u
#define SD_DRVMSG_DMARX_FEERR      0x10u
#define SD_DRVMSG_DMARx_DMEERR     0x20u

/*
 * the following Timeout is useful to give the control back to the applications
 * in case of errors in either BSP_SD_ReadCpltCallback() or BSP_SD_WriteCpltCallback()
 * the value by default is as defined in the BSP platform driver otherwise 30 secs
 */
#define SD_TIMEOUT 30 * 1000

#define SD_DEFAULT_BLOCK_SIZE 512

/** @defgroup SD_Exported_Types_Group4 Card Specific Data: CSD Register 
  * @{
  */
typedef struct
{
  volatile uint8_t  CSDStruct;            /*!< CSD structure                         */
  volatile uint8_t  SysSpecVersion;       /*!< System specification version          */
  volatile uint8_t  Reserved1;            /*!< Reserved                              */
  volatile uint8_t  TAAC;                 /*!< Data read access time 1               */
  volatile uint8_t  NSAC;                 /*!< Data read access time 2 in CLK cycles */
  volatile uint8_t  MaxBusClkFrec;        /*!< Max. bus clock frequency              */
  volatile uint16_t CardComdClasses;      /*!< Card command classes                  */
  volatile uint8_t  RdBlockLen;           /*!< Max. read data block length           */
  volatile uint8_t  PartBlockRead;        /*!< Partial blocks for read allowed       */
  volatile uint8_t  WrBlockMisalign;      /*!< Write block misalignment              */
  volatile uint8_t  RdBlockMisalign;      /*!< Read block misalignment               */
  volatile uint8_t  DSRImpl;              /*!< DSR implemented                       */
  volatile uint8_t  Reserved2;            /*!< Reserved                              */
  volatile uint32_t DeviceSize;           /*!< Device Size                           */
  volatile uint8_t  MaxRdCurrentVDDMin;   /*!< Max. read current @ VDD min           */
  volatile uint8_t  MaxRdCurrentVDDMax;   /*!< Max. read current @ VDD max           */
  volatile uint8_t  MaxWrCurrentVDDMin;   /*!< Max. write current @ VDD min          */
  volatile uint8_t  MaxWrCurrentVDDMax;   /*!< Max. write current @ VDD max          */
  volatile uint8_t  DeviceSizeMul;        /*!< Device size multiplier                */
  volatile uint8_t  EraseGrSize;          /*!< Erase group size                      */
  volatile uint8_t  EraseGrMul;           /*!< Erase group size multiplier           */
  volatile uint8_t  WrProtectGrSize;      /*!< Write protect group size              */
  volatile uint8_t  WrProtectGrEnable;    /*!< Write protect group enable            */
  volatile uint8_t  ManDeflECC;           /*!< Manufacturer default ECC              */
  volatile uint8_t  WrSpeedFact;          /*!< Write speed factor                    */
  volatile uint8_t  MaxWrBlockLen;        /*!< Max. write data block length          */
  volatile uint8_t  WriteBlockPaPartial;  /*!< Partial blocks for write allowed      */
  volatile uint8_t  Reserved3;            /*!< Reserved                              */
  volatile uint8_t  ContentProtectAppli;  /*!< Content protection application        */
  volatile uint8_t  FileFormatGroup;      /*!< File format group                     */
  volatile uint8_t  CopyFlag;             /*!< Copy flag (OTP)                       */
  volatile uint8_t  PermWrProtect;        /*!< Permanent write protection            */
  volatile uint8_t  TempWrProtect;        /*!< Temporary write protection            */
  volatile uint8_t  FileFormat;           /*!< File format                           */
  volatile uint8_t  ECC;                  /*!< ECC code                              */
  volatile uint8_t  CSD_CRC;              /*!< CSD CRC                               */
  volatile uint8_t  Reserved4;            /*!< Always 1                              */
}SD_CardCSDType;

typedef enum
{
  SD_CSR_STATE_IDLE  = 0x00000000u,
  SD_CSR_STATE_READY = 0x00000001u,   /*!< Card state is ready                     */
  SD_CSR_STATE_IDENTIFICATION,        /*!< Card is in identification state         */
  SD_CSR_STATE_STANDBY,               /*!< Card is in standby state                */
  SD_CSR_STATE_TRANSFER,              /*!< Card is in transfer state               */
  SD_CSR_STATE_SENDING,               /*!< Card is sending an operation            */
  SD_CSR_STATE_RECEIVING,             /*!< Card is receiving operation information */
  SD_CSR_STATE_PROGRAMMING,           /*!< Card is in programming state            */
  SD_CSR_STATE_DISCONNECTED,          /*!< Card is disconnected                    */
}SD_CardCSRStateEnum;

typedef struct
{
  uint32_t type;                     /* Specifies the card Type                       */
  uint32_t version;                  /* Specifies the card version                    */
  uint32_t sclass;                   /* Specifies the class of the card class         */
  uint32_t rca;                      /* Specifies the Relative Card Address           */
  uint32_t block_nbr;                /* Specifies the Card Capacity in blocks         */
  uint32_t block_size;               /* Specifies one block size in bytes             */
  uint32_t logical_block_nbr;        /* Specifies the Card logical Capacity in blocks */
  uint32_t logical_block_size;       /* Specifies logical block size in bytes         */
  uint32_t csd_buf[4];               /* SD card specific data table         */
  uint32_t cid_buf[4];               /* SD card identification number table */
  volatile uint32_t error_code;
  SD_CardCSDType csd;
  SDIO_InitTypeDef init_1b;
  SDIO_InitTypeDef init_4b;
}SD_CardInfoType;

typedef enum
{
  SD_DRVMSG_NULL = 0u,
  SD_DRVMSG_SDIOTRANS_COMPLETE,
  SD_DRVMSG_SDIOTRANS_ERROR,
  SD_DRVMSG_DMATX_COMPLETE,
  SD_DRVMSG_DMARX_COMPLETE,
  SD_DRVMSG_DMATX_ERROR,
  SD_DRVMSG_DMARX_ERROR,
}SD_DriverMessageTypeEnum;

typedef struct
{
  SD_DriverMessageTypeEnum msgtype;
  volatile uint32_t errcode;
}SD_DriverMessageStru;

#define SD_DRVMSG_QUE_LENGTH          5
#define SD_DRVMSG_QUE_ITEMSIZE        sizeof(SD_DriverMessageStru)

extern uint8_t sd_diskio_status(SD_CardInfoType *sdinfo);
extern uint8_t sd_diskio_check_status_with_timeout(SD_CardInfoType *sdinfo, uint32_t timeout);
extern uint8_t sd_diskio_initialize(SD_CardInfoType *sdinfo);
extern uint8_t sd_diskio_read_blocks(SD_CardInfoType *sdinfo, uint8_t *pdata, uint32_t blockaddr, uint32_t numofblocks);
extern uint8_t sd_diskio_write_blocks(SD_CardInfoType *sdinfo, const uint8_t *pdata, uint32_t blockaddr, uint32_t numofblocks);
extern uint8_t sd_diskio_ioctl(SD_CardInfoType *sdinfo, uint8_t cmd, void *buff);
extern uint8_t sd_diskio_erase(SD_CardInfoType *sdinfo, uint32_t blockstartaddr, uint32_t blockendaddr);
extern void sd_dma_rx_isr(void);
extern void sd_dma_tx_isr(void);
extern void sd_sdio_isr_dma(void);

#endif /* __SDDRIVER_H */
